#pragma once

#include "Singleton.h"
#include "Team.h"

class TeamMgr : public WheelTimerOwner, public WheelRoutineType, public Singleton<TeamMgr>
{
public:
	TeamMgr();
	virtual ~TeamMgr();

	GErrorCode HandleTeamCreate(Character* pChar);
	GErrorCode HandleTeamInvite(Character* pChar, ObjGUID targetGuid);
	GErrorCode HandleTeamInviteResp(Character* pChar, uint32 teamId, bool isAgree);
	GErrorCode HandleTeamApply(Character* pChar, uint32 teamId);
	GErrorCode HandleTeamApplyResp(Character* pChar, ObjGUID applicantGuid, bool isAgree);
	GErrorCode HandleTeamLeave(Character* pChar);
	GErrorCode HandleTeamKick(Character* pChar, ObjGUID targetGuid);
	GErrorCode HandleTeamTransfer(Character* pChar, ObjGUID targetGuid);

	void OnCharacterOnline(Character* pChar);
	void OnCharacterOffline(Character* pChar);

	Team* GetTeam(uint32 teamId) const;

private:
	virtual WheelTimerMgr *GetWheelTimerMgr();

	void RemoveInviteApplyRelation(Character* pChar);
	void OnInviteRelationExpire(uint32 teamId, Character* pTarget);
	void OnApplyRelationExpire(uint32 teamId, Character* pApplicant);

	void AddTeamMember(Team* pTeam, Character* pChar);
	void RemoveTeamMember(Character* pChar, Character* pKicker);
	void DisbandTeam(uint32 teamId);

	struct InviteInfo {
		Character* pInviter;
		Character* pTarget;
		uint32 timer;
	};
	struct ApplyInfo {
		Character* pApplicant;
		uint32 timer;
	};
	struct TeamInfo {
		Team* pTeam;
		std::unordered_map<ObjGUID, InviteInfo> inviteList;  // key is target guid.
		std::unordered_map<ObjGUID, ApplyInfo> applyList;  // key is applicant guid.
	};
	std::unordered_map<uint32, TeamInfo> m_allTeamInfos;
	uint32 m_teamSeed;
};

#define sTeamMgr (*TeamMgr::instance())
